package com.yashi.springmvcjbpm.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.jbpm.api.Configuration;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.model.ActivityCoordinates;

public class ImageShow {
	private ProcessEngine processEngine;
	GetConnection connection = new GetConnection();

	public ProcessEngine getProcessEngine() {
		processEngine = Configuration.getProcessEngine();
		return processEngine;
	}

	/**
	 * 获得流程定义图片输入流
	 * 
	 * @param processInstanceId
	 * @param request
	 * @return
	 */
	public InputStream findProcessInstancePic(String processInstanceId) {
		// 获得流程实例processInstance，对于已完结的流程processInstance为null,所以应该通过HistoryProcessInstance查询processDefinitionId
		// 一般情况下processInstanceId与ExecutionId(newSite.10001)会相同,但在fork-join分叉流程时会不同，
		// ProcessInstance processInstance =
		// processEngine.getExecutionService().findProcessInstanceById(processInstanceId);
		// String processDefinitionId = processInstance.getProcessDefinitionId();
		HistoryService hs = getProcessEngine().getHistoryService();
		HistoryProcessInstance hpi = hs.createHistoryProcessInstanceQuery().processInstanceId(processInstanceId)
				.uniqueResult();
		String processDefinitionId = hpi.getProcessDefinitionId();
		RepositoryService repositoryService = getProcessEngine().getRepositoryService();
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).uniqueResult();
		String deploymentId = processDefinition.getDeploymentId();
		// 获取图片名称，如果发布流程时只发布了 xml 文件 , imageName就会是null,
		// 所以需要同时发布png图片
		String imageName = processDefinition.getImageResourceName();
		return repositoryService.getResourceAsStream(deploymentId, imageName);
	}

	/**
	 * 获得流程当前活动节点的坐标
	 * 
	 * @param id
	 * @return
	 */
	public ActivityCoordinates findActivityCoordinates(String processInstanceId) {
		// 对于已经完结的流程 processInstance为NUll，将无法查询end节点
		RepositoryService repositoryService = getProcessEngine().getRepositoryService();
		ProcessInstance processInstance = getProcessEngine().getExecutionService()
				.findProcessInstanceById(processInstanceId);
		List<CompleteTaskHistory> listHist = new ArrayList<>();
		String processDefinitionId;
		String activtyName;
		if (null == processInstance || processInstance.isSuspended()) {
			// 已完结流程 processInstance为NUll 从HistoryProcessInstance获得需要的信息
			HistoryService hs = getProcessEngine().getHistoryService();
			HistoryProcessInstance ss = hs.createHistoryProcessInstanceQuery().processInstanceId(processInstanceId)
					.uniqueResult();
			// 获得end节点
			activtyName = ss.getEndActivityName();
			processDefinitionId = ss.getProcessDefinitionId();
		} else {
			// 未完结的流程
			processDefinitionId = processInstance.getProcessDefinitionId();
			Set<String> activtyNames = processInstance.findActiveActivityNames();
			activtyName = activtyNames.iterator().next();
		}
		return repositoryService.getActivityCoordinates(processDefinitionId, activtyName);

	}

	public List<CompleteTaskHistory> findActivityCoordinatesList(String processInstanceId) {
		// 对于已经完结的流程 processInstance为NUll，将无法查询end节点
		RepositoryService repositoryService = getProcessEngine().getRepositoryService();
		ProcessInstance processInstance = getProcessEngine().getExecutionService()
				.findProcessInstanceById(processInstanceId);
		List<CompleteTaskHistory> listHist = new ArrayList<>();
		String processDefinitionId;
		String activtyName;
		if (null == processInstance || processInstance.isSuspended()) {
			// 已完结流程 processInstance为NUll 从HistoryProcessInstance获得需要的信息
			HistoryService hs = getProcessEngine().getHistoryService();
			HistoryProcessInstance ss = hs.createHistoryProcessInstanceQuery().processInstanceId(processInstanceId)
					.uniqueResult();
			// 获得end节点
			activtyName = ss.getEndActivityName();
			processDefinitionId = ss.getProcessDefinitionId();
			ActivityCoordinates ac = repositoryService.getActivityCoordinates(processDefinitionId, activtyName);
			CompleteTaskHistory cth = getEndTask(processInstanceId);
			cth.setX(ac.getX()+7);
			cth.setY(ac.getY()+17);
			cth.setWidth(ac.getWidth());
			cth.setHeight(ac.getHeight());

			listHist.add(cth);
		} else {
			// 未完结的流程
			processDefinitionId = processInstance.getProcessDefinitionId();

			Set<String> activtyNames = processInstance.findActiveActivityNames();
			activtyName = activtyNames.iterator().next();

			ActivityCoordinates ac = repositoryService.getActivityCoordinates(processDefinitionId, activtyName);
			CompleteTaskHistory cth = getNowTask(processInstanceId, activtyName);
			cth.setX(ac.getX());
			cth.setY(ac.getY());
			cth.setWidth(ac.getWidth());
			cth.setHeight(ac.getHeight());

			listHist.add(cth);
		}
		System.out.println("list=" + listHist);
		return listHist;

	}

	/**
	 * 根据流程实例ID查询出该流程实例经过的节点的名称
	 * 
	 * @param processId
	 * @return
	 */
	public List<CompleteTaskHistory> findHistoryActivityInfo(String processId) {
		HistoryService historyService = getProcessEngine().getHistoryService();
		RepositoryService repositoryService = getProcessEngine().getRepositoryService();
		HistoryService hs = getProcessEngine().getHistoryService();
		// 已完结流程 processInstance为NUll 可从HistoryProcessInstance获得需要的信息
		HistoryProcessInstance hpi = hs.createHistoryProcessInstanceQuery().processInstanceId(processId).uniqueResult();
		List<HistoryActivityInstance> hisIns = historyService.createHistoryActivityInstanceQuery()
				.processInstanceId(processId).list();
		String pdId = hpi.getProcessDefinitionId();
		List<CompleteTaskHistory> listHist = new ArrayList<>();
		// 获得当前活动的节点
		ActivityCoordinates nowac = findActivityCoordinates(processId);
		for (int i = 0; i < hisIns.size(); i++) {
			HistoryActivityInstance hai = hisIns.get(i);
			ActivityCoordinates ac = repositoryService.getActivityCoordinates(pdId, hai.getActivityName());
			// 如果当前历史节点等于活动节点，则不想集合中再次添加
			if (ac != nowac) {
				// 把节点的坐标、宽高加入到CompleteTaskHistory对象中
				CompleteTaskHistory cth = getCompleteTaskHistory(processId, hai.getStartTime().toString(),
						hai.getActivityName());
				boolean flag = isTaskType(hai.getActivityName(), processId, hai.getStartTime().toString());
				if(flag) {
					cth.setX(ac.getX());
					cth.setY(ac.getY());
					cth.setWidth(ac.getWidth());
					cth.setHeight(ac.getHeight());					
				}else {
					cth.setX(ac.getX()+4);
					cth.setY(ac.getY()+4);
					cth.setWidth(ac.getWidth()+4);
					cth.setHeight(ac.getHeight()+4);
				}

				listHist.add(cth);
			}
		}
		return listHist;
	}

	private CompleteTaskHistory getCompleteTaskHistory(String processId, String startTime, String activityName) {
		boolean flag = isTaskType(activityName, processId, startTime);
		CompleteTaskHistory completeTaskHistory = new CompleteTaskHistory();
		if (flag) {
			String queryString = "SELECT a.ACTIVITY_NAME_ taskName,b.CREATE_ start,b.END_ end,b.ASSIGNEE_ assignee from jbpm4_hist_actinst a LEFT JOIN jbpm4_hist_task b on a.HTASK_=b.DBID_"
					+ " WHERE a.EXECUTION_='" + processId + "' and a.START_='" + startTime + "' and a.ACTIVITY_NAME_='"
					+ activityName + "'";
			System.out.println("sql=" + queryString);

			try {
				Connection con = connection.getCon();
				Statement st = con.createStatement();
				ResultSet rs = st.executeQuery(queryString);
				while (rs.next()) {
					completeTaskHistory.setCompletionTime(rs.getString("end"));
					completeTaskHistory.setReceiveTime(startTime);
					completeTaskHistory.setTasker_role(activityName);
					completeTaskHistory.setTasker(rs.getString("assignee"));
				}
			} catch (ClassNotFoundException | IOException | SQLException e) {
				e.printStackTrace();
			}
		}else {
			String queryString = "SELECT a.TRANSITION_ taskName,a.START_ start,a.END_ end from jbpm4_hist_actinst a "
					+ " WHERE a.EXECUTION_='" + processId + "' and a.START_='" + startTime + "' and a.ACTIVITY_NAME_='"
					+ activityName + "'";
			System.out.println("sql=" + queryString);

			try {
				Connection con = connection.getCon();
				Statement st = con.createStatement();
				ResultSet rs = st.executeQuery(queryString);
				while (rs.next()) {
					completeTaskHistory.setCompletionTime(rs.getString("end"));
					completeTaskHistory.setReceiveTime(startTime);
					completeTaskHistory.setTasker_role(rs.getString("taskName"));
				}
			} catch (ClassNotFoundException | IOException | SQLException e) {
				e.printStackTrace();
			}
		}
		return completeTaskHistory;
	}

	private boolean isTaskType(String activityName, String processId, String startTime) {
		String sql = "select a.TYPE_ type from jbpm4_hist_actinst a where a.EXECUTION_='" + processId
				+ "' and a.START_='" + startTime + "' and a.ACTIVITY_NAME_='" + activityName + "'";
		boolean flag = false;
		try {
			Connection con = connection.getCon();
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(sql);
			while (rs.next()) {
				String type = rs.getString("type");
				if (type.equals("task"))
					flag = true;
			}
		} catch (ClassNotFoundException | IOException | SQLException e) {
			e.printStackTrace();
		}
		return flag;
	}

	private CompleteTaskHistory getNowTask(String processInstanceId, String activtyName) {
		String queryString = "select a.ACTIVITYNAME_ taskName,b.START_ startTime,b.END_ endTime,c.ASSIGNEE_ assignee from jbpm4_execution a left join jbpm4_hist_actinst b on a.HISACTINST_=b.DBID_ \r\n"
				+ " left join jbpm4_hist_task c on c.DBID_=b.HTASK_ where a.ID_='" + processInstanceId + "'";
		System.out.println("sql=" + queryString);
		CompleteTaskHistory completeTaskHistory = new CompleteTaskHistory();
		GetConnection connection = new GetConnection();
		try {
			Connection con = connection.getCon();
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(queryString);
			while (rs.next()) {
				completeTaskHistory.setReceiveTime(rs.getString("startTime"));
				completeTaskHistory.setTasker_role(rs.getString("taskName"));
				completeTaskHistory.setTasker(rs.getString("assignee"));
			}
		} catch (ClassNotFoundException | IOException | SQLException e) {
			e.printStackTrace();
		}

		return completeTaskHistory;

	}
	private CompleteTaskHistory getEndTask(String processInstanceId) {
		String queryString = "select END_ endTime from jbpm4_hist_procinst a  where a.ID_='" + processInstanceId + "' and a.STATE_='ended'";
		System.out.println("sql=" + queryString);
		CompleteTaskHistory completeTaskHistory = new CompleteTaskHistory();
		GetConnection connection = new GetConnection();
		try {
			Connection con = connection.getCon();
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery(queryString);
			while (rs.next()) {
				completeTaskHistory.setReceiveTime(rs.getString("endTime"));
				completeTaskHistory.setCompletionTime(rs.getString("endTime"));
				completeTaskHistory.setTasker_role("结束");
			}
		} catch (ClassNotFoundException | IOException | SQLException e) {
			e.printStackTrace();
		}
		
		return completeTaskHistory;
		
	}
}
